#!/usr/bin/env python

import sys, os
import csv

def usage():
    print '''Usage: %s full.csv''' % sys.argv[0]
    print '''
    - Go to Conference Reporting
    - Choose "Reviews By Person - Full Reviews"
    - Export to CSV and save as full.csv

This script can be used during the review process to track reviewer progress.
Remember that some reviewers wait to upload their reviews.  You can remind them
that they don't have to wait till the end, but can send incremental uploads.

The report prints the submissions sorted by percent complete.  This lets you
identify the submissions which need reviewers easily.  As the deadline
approaches and reviewers are delinquent, you can tell the delinquents to focus
on the submissions which need reviews.

The program also prints out the reviewers sorted by the percent complete.  This
lets you know who to prod.
    '''
    sys.exit(1)

class Status:
    '''
        Status class keeps track of the review status for submissions/reviewers
    '''
    def __init__(self):
        self.Complete = 0
        self.Total = 0

    def add(self, complete):
        self.Total += 1
        if complete:
            self.Complete += 1

    def isComplete(self):
        return self.Complete and self.Total == self.Complete

class Report:
    '''
        Report to keep track of the reviewers/submissions and how much of each
        is complete.
    '''
    def __init__(self):
        self.List = {}

    def question(self, id, complete):
        if not self.List.has_key(id):
            self.List[id] = Status()
        self.List[id].add(complete)

    def sumComplete(self):
        ncomplete = 0
        for s in self.List:
            if self.List[s].isComplete():
                ncomplete += 1
        return (ncomplete, len(self.List))

def percent(num, total):
    ''' Pretty print percentages '''
    return '%5.1f%% (%2d of %2d)' % (num*100.0/total, num, total)

# List of reviewers
RList = {}
# List of submissions
SList = {}

def process(row):
    # Make the name nice (first name first)
    name = row[1].split(',')
    name.reverse()
    name = ' '.join(name)
    name = name.split()
    for i in range(len(name)):
        name[i] = name[i].capitalize()
    rev = ' '.join(name)

    sub = row[3]
    answer = row[7].strip()
    if not RList.has_key(rev):
        RList[rev] = Report()
    RList[rev].question(sub, answer)
    if not SList.has_key(sub):
        SList[sub] = Report()
    SList[sub].question(rev, answer)

def report(report):
    # Print out a completion report
    lines = []
    ndone = total = 0
    counts = {}
    for r in report:
        num, tot = report[r].sumComplete()
        counts[num] = counts.get(num, 0) + 1
        ndone += num
        total += tot
        lines.append('%-12s %s' % (percent(num, tot), r))
    lines.sort(reverse=True)
    print '\n'.join(lines)
    print '-'*10, percent(ndone, total), 'of', len(lines), '-'*10
    return counts
        

def main():
    if len(sys.argv) < 2:
        usage()

    # Process the full reviews
    fp = csv.reader(open(sys.argv[1], 'r'))
    for title in fp:
        break
    if len(title) < 8 or title[1] != 'Reviewer' \
                or title[3] != 'Submission' \
                or title[4] != 'Title' \
                or title[5] != 'QuestionNumber' \
                or title[7] != 'Answer':
        print 'Unexpected title row', row
        usage()

    for row in fp:
        if len(row) < 8:
            print 'Skipping row', row
        else:
            process(row)

    # Print out the reviewer status
    print '='*20, 'REVIEWERS', '='*20
    report(RList)
    print

    # Print out the submission status
    print '='*20, 'SUBMISSIONS', '='*20

    # Print out summary information
    counts = report(SList)
    print '%7s %s' % ('Reads', 'Reviews')
    for l in counts:
        print '%7d %d' % (l, counts[l])

if __name__ == '__main__':
    main()
